const http = require("http");
const path = require("path");
const fs = require("fs");
const esbuild = require("esbuild");
const CssModulesPlugin = require('esbuild-css-modules-plugin');

const WebSocket = require("ws");

const PORT = 3000;

// 启动服务器
http
  .createServer(async (req, res) => {
    let filePath = "";

    if (req.url === "/") {
      // 返回 index.html
      filePath = path.join(__dirname, "public", "index.html");
    } else if (req.url.startsWith("/src")) {
      // 处理 /src 目录下的文件，使用 esbuild 进行实时编译
      filePath = path.join(__dirname, req.url);

      // 编译 JSX 文件
      if (filePath.endsWith(".js") || filePath.endsWith(".jsx")) {
        try {
          const result = await esbuild.build({
            entryPoints: [filePath],
            bundle: true,
            write: false,
            format: "esm",
            loader: {
              ".js": "jsx",
              ".css": "text",
            },
            plugins: [
              CssModulesPlugin({
                // @see https://github.com/indooorsman/esbuild-css-modules-plugin/blob/main/index.d.ts for more details
                force: true,
                emitDeclarationFile: true,
                localsConvention: 'camelCaseOnly',
                namedExports: true,
                inject: false
              })
            ]
          });

          res.writeHead(200, { "Content-Type": "application/javascript" });
          res.end(result.outputFiles[0].text, "utf-8");
          return;
        } catch (error) {
          res.writeHead(500, { "Content-Type": "text/plain" });
          res.end("Error during JSX transformation");
          return;
        }
      }
    } else {
      // 处理静态资源文件（如 CSS）
      filePath = path.join(__dirname, "public", req.url);
    }

    const extname = path.extname(filePath);
    const contentType =
      {
        ".html": "text/html",
        ".js": "application/javascript",
        ".css": "text/css",
        ".json": "application/json",
      }[extname] || "text/plain";

    // 读取文件内容并返回
    fs.readFile(filePath, (err, content) => {
      if (err) {
        res.writeHead(404, { "Content-Type": "text/plain" });
        res.end("404 Not Found");
      } else {
        res.writeHead(200, { "Content-Type": contentType });
        res.end(content, "utf-8");
      }
    });
  })
  .listen(PORT, () => {
    console.log(`Server running at http://localhost:${PORT}`);
  });

// 依赖预构建
const prebuiltDeps = async () => {
  await esbuild.build({
    entryPoints: ["src/main.js"],
    bundle: true,
    outfile: "dist/bundle.js",
    format: "esm",
    external: ["react", "react-dom"],
    loader: {
      ".js": "jsx", // 启用 JSX 语法支持
      ".css": "text", // 处理 CSS 文件为文本
    },
    plugins: [
      CssModulesPlugin({
        // @see https://github.com/indooorsman/esbuild-css-modules-plugin/blob/main/index.d.ts for more details
        force: true,
        emitDeclarationFile: true,
        localsConvention: 'camelCaseOnly',
        namedExports: true,
        inject: false
      })
    ],
    jsxFactory: "React.createElement",
    jsxFragment: "React.Fragment",
  });
};

// HMR（热更新）实现
const wss = new WebSocket.Server({ port: 3001 });

fs.watch(path.join(__dirname, "src"), (eventType, filename) => {
  if (filename && filename.endsWith(".js")) {
    wss.clients.forEach((client) => {
      if (client.readyState === WebSocket.OPEN) {
        client.send(JSON.stringify({ type: "reload" }));
      }
    });
  }
});

prebuiltDeps();
